#!/usr/bin/env python3
"""
LightPort - 轻量智能端口扫描器
一个具有防火墙绕过能力的智能端口扫描工具
"""

import argparse
import asyncio
import ipaddress
import sys
from pathlib import Path
from rich.console import Console
from rich.table import Table
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.panel import Panel
from rich.layout import Layout
import json
from datetime import datetime

from core.scanner import LightScanner
from core.bypass import FirewallBypass
from core.service_detector import ServiceDetector
from utils.logger import setup_logger
from utils.output import OutputFormatter

console = Console()

BANNER = """
[bold cyan]
╦  ╦┌─┐┬─┐┌┐┌┌─┐┌┬┐┌─┐┬─┐    ┬─┐┌─┐┌─┐┌─┐┌┐┌
╚╗╔┘├┤ ├┬┘││││ │ │ ├┤ ├┬┘    ├┬┘├┤ └─┐├┤ │││
 ╚╝ └─┘┴└─┘└┘└─┘ ┴ └─┘┴└─────┴└─└─┘└─┘└─┘┘└┘
[/bold cyan]
[dim]LightPort - 智能端口扫描器 v1.0[/dim]
"""

def parse_targets(targets):
    """解析目标IP地址列表"""
    ip_list = []
    for target in targets:
        try:
            # 处理CIDR网段
            if '/' in target:
                network = ipaddress.ip_network(target, strict=False)
                ip_list.extend([str(ip) for ip in network.hosts()])
            else:
                # 处理单个IP
                ipaddress.ip_address(target)
                ip_list.append(target)
        except ValueError as e:
            console.print(f"[red]错误的目标格式: {target} - {e}[/red]")
            sys.exit(1)
    return ip_list

def parse_ports(port_str):
    """解析端口范围"""
    ports = []
    for part in port_str.split(','):
        if '-' in part:
            start, end = map(int, part.split('-'))
            ports.extend(range(start, end + 1))
        else:
            ports.append(int(part))
    return sorted(set(ports))

async def main():
    """主函数"""
    parser = argparse.ArgumentParser(
        description="LightPort - 轻量智能端口扫描器",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  python lightport.py 192.168.1.1 -p 1-1000
  python lightport.py 192.168.1.0/24 -p 80,443 --stealth
  python lightport.py 10.0.0.1 -p 1-65535 --bypass --spoof 1.1.1.1
        """
    )
    
    parser.add_argument('targets', nargs='+', help='目标IP或CIDR网段')
    parser.add_argument('-p', '--ports', default='1-1000', 
                       help='端口范围 (默认: 1-1000)')
    parser.add_argument('--stealth', action='store_true',
                       help='使用隐蔽扫描模式')
    parser.add_argument('--bypass', action='store_true',
                       help='启用防火墙绕过')
    parser.add_argument('--spoof', metavar='IP',
                       help='伪造源IP地址')
    parser.add_argument('--timeout', type=int, default=3,
                       help='超时时间 (秒)')
    parser.add_argument('--threads', type=int, default=100,
                       help='并发线程数')
    parser.add_argument('--output', metavar='FILE',
                       help='输出结果到文件 (JSON格式)')
    parser.add_argument('--verbose', '-v', action='store_true',
                       help='详细输出')
    
    args = parser.parse_args()
    
    # 显示banner
    console.print(BANNER)
    
    # 解析目标
    targets = parse_targets(args.targets)
    ports = parse_ports(args.ports)
    
    console.print(f"[green]目标: {len(targets)} 个主机[/green]")
    console.print(f"[green]端口: {len(ports)} 个端口[/green]")
    
    # 初始化扫描器
    scanner = LightScanner(
        stealth_mode=args.stealth,
        bypass_enabled=args.bypass,
        spoof_ip=args.spoof,
        timeout=args.timeout,
        max_threads=args.threads,
        verbose=args.verbose
    )
    
    # 开始扫描
    start_time = datetime.now()
    
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
    ) as progress:
        
        task = progress.add_task("扫描中...", total=len(targets) * len(ports))
        
        results = await scanner.scan_targets(targets, ports, progress, task)
    
    end_time = datetime.now()
    duration = (end_time - start_time).total_seconds()
    
    # 格式化输出
    formatter = OutputFormatter(console)
    formatter.display_results(results, duration)
    
    # 保存结果
    if args.output:
        with open(args.output, 'w') as f:
            json.dump(results, f, indent=2, default=str)
        console.print(f"\n[green]结果已保存到: {args.output}[/green]")

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        console.print("\n[yellow]扫描被用户中断[/yellow]")
        sys.exit(0)
